from django.contrib.auth import login, authenticate, logout
from django.http import HttpResponse, HttpResponseBadRequest, JsonResponse
from django.shortcuts import render

# Create your views here.
from django.views import View

from libs.captcha import captcha
from libs.captcha.captcha import captcha
from django_redis import get_redis_connection
from utils.response_code import RETCODE
from random import randint
from libs.yuntongxun.sms import CCP
from users.models import User
from django.db import DatabaseError
from django.shortcuts import render, redirect
from django.urls import reverse
import logging
import re

logger=logging.getLogger('django')
#定义用户注册视图

class ImageCodeView(View):
    def get(self, request):
        uuid = request.GET.get('uuid')

        if uuid is None:
            return HttpResponseBadRequest('请求参数未携带uuid')

        text, image = captcha.generate_captcha()

        redis_conn = get_redis_connection('default')

        redis_conn.setex('img_%s' % uuid, 300, text)

        return HttpResponse(image, content_type='image/jpeg')

class SmsCodeView(View):
    def get(self, request):
        mobile = request.GET.get('mobile')
        image_code_client = request.GET.get('image_code')
        uuid = request.GET.get('uuid')
        if not all([mobile, image_code_client , uuid]):
            return JsonResponse({'code':RETCODE.NECESSARYPARAMERR,'errorMsg':'缺少必传参数'})
        redis_conn = get_redis_connection('default')
        image_code_server = redis_conn.get('img_%s' % uuid)
        if image_code_server is None:
            return JsonResponse({'code':RETCODE.IMAGECODEERR,'errormsg':'图形验证码不在'})
        try:
            redis_conn.delete('img:%s' % uuid)
        except Exception as e:
            logger.error(e)
        image_code_server = image_code_server.decode()  # bytes转字符串
        if image_code_client.lower() != image_code_server.lower():  # 转小写后比较
            return JsonResponse({'code': RETCODE.IMAGECODEERR, 'errmsg':'输入图形验证码有误'})
        sms_code = '%04d' % randint(0, 9999)
        logger.info(sms_code)
        redis_conn.setex('sms:%s' % mobile, 300, sms_code)
        CCP().send_template_sms(mobile, [sms_code, 5], 1)
        return JsonResponse({'code': RETCODE.OK, 'errmsg': '发送短信成功'})


class RegisterView(View):
    # 处理 GET 请求
    def get(self, request):
        """
        提供注册界面

在users/urls.py中，无须再次添加注册路由，已经定义
        :param request: 请求对象
        :return:注册界面
        """
        return render(request, 'register.html')

    # 处理 POST 请求
    def post(self, request):
        # 接收参数
        mobile = request.POST.get('mobile')
        password = request.POST.get('password')
        password2 = request.POST.get('password2')
        sms_code_client = request.POST.get('sms_code')
        if not all([mobile, password, password2, sms_code_client]):
            return HttpResponseBadRequest('缺少必传参数')
            # 判断手机号是否合法
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return HttpResponseBadRequest('请输入正确的手机号码')
            # 判断密码是否是8-20个数字
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return HttpResponseBadRequest('请输入8-20位的密码')
            # 判断两次密码是否一致
        if password != password2:
            return HttpResponseBadRequest('两次输入的密码不一致')
            # 验证短信验证码
        redis_conn = get_redis_connection('default')
        sms_code_server = redis_conn.get('sms:%s' % mobile)
        if sms_code_server is None:
            return HttpResponseBadRequest('短信验证码已过期')
        if sms_code_client != sms_code_server.decode():
            return HttpResponseBadRequest('短信验证码错误')
        # 保存注册数据
        try:
            user = User.objects.create_user(username=mobile, mobile=mobile,
                                            password=password)
        except DatabaseError as e:
            logger.error(e)
            return HttpResponseBadRequest('注册失败')
        # 响应注册结果
        login(request, user)
        response = redirect(reverse('home:index'))
        # 1.登录状态，会话结束后自动过期
        response.set_cookie('is_login', True)
        # 2.设置用户名有效期7天
        response.set_cookie('username', user.username, max_age=7 * 24 * 3600)
        return response


class LoginView(View):
    def get(self, request):
        """
       提供登录界面
       :param request: 请求对象
       :return:登录界面
       """

        return render(request, 'index.html')

    def post(self, request):
        # 接受参数
        mobile = request.POST.get('mobile')
        password = request.POST.get('password')
        remember = request.POST.get('remember')
        # 校验参数
        # 判断参数是否齐全
        if not all([mobile, password]):
            return HttpResponseBadRequest('缺少必传参数')
        # 判断手机号是否正确
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return HttpResponseBadRequest('请输入正确的手机号')
        # 判断密码是否是8-20个数字
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return HttpResponseBadRequest('密码最少8位，最长20位')
        # 认证登录用户
        # 认证字段已经在User模型中的USERNAME_FIELD = 'mobile'修改
        user = authenticate(mobile=mobile, password=password)
        if user is None:
            return HttpResponseBadRequest('用户名或密码错误')
        # 实现状态保持
        login(request, user)
        # 响应登录结果
        response = redirect(reverse('home:index'))
        # 设置状态保持的周期
        if remember != 'on':
            # 没有记住用户：浏览器会话结束就过期
            request.session.set_expiry(0)
            # 设置cookie
            response.set_cookie('is_login', True)
            response.set_cookie('username', user.username, max_age=30 * 24 *3600)
        else:
            # 记住用户：None表示两周后过期
            request.session.set_expiry(None)
            # 设置cookie
            response.set_cookie('is_login', True, max_age=14 * 24 * 3600)
            response.set_cookie('username', user.username, max_age=30 * 24 *3600)
            # 返回响应
        return response

class LogoutView(View):
    def get(self,request):
         # 清理session
        logout(request)
         # 退出登录，重定向到登录页
        response = redirect(reverse('home:index'))
         # 退出登录时清除cookie中的登录状态
        response.delete_cookie('is_login')
         # 返回响应
        return response


